
#include "fxcc/imgui/Layer.h"

using namespace fxcc::imgui;

Layer::Layer(const std::string& title, ImGuiWindowFlags flag) : m_Title(title), m_Flag(flag)
{

}

void Layer::OnDestroy()
{

};

bool Layer::MenuItem()
{
    if (this->m_Children.size() == 0)
    {
        bool res = ImGui::MenuItem(this->m_Title.c_str(), nullptr, &m_Open);
        return res;
    }
    else
    {

        if (ImGui::BeginMenu(this->m_Title.c_str()), &m_Open)
        {
            for (auto child : m_Children)
            {
                child->MenuItem();
            }
        }
    }
};

void Layer::Inst()
{

    if (m_Open)
    {
        if (m_Rendering = ImGui::Begin(m_Title.c_str(), &m_Open, m_Flag))
        {
            m_WindowPos = ImGui::GetWindowPos();
            m_WindowSize = ImGui::GetWindowSize();

            m_IsFocused = ImGui::IsWindowFocused();
            m_IsHovered = ImGui::IsWindowHovered();
            ViewFunc();


            m_IsAnyItemHovered = ImGui::IsAnyItemHovered();
            m_IsAnyItemActive = ImGui::IsAnyItemActive();
            m_IsAnyItemFocused = ImGui::IsAnyItemFocused();

            OnMarqueeSelection();


            
        }
        ImGui::End();
    };

    for (auto& child : m_Children)
    {
        child->Inst();
    }
}

bool fxcc::imgui::Layer::GetMarqueeSelectionFlag()
{
    return true;
}

void fxcc::imgui::Layer::OnMarqueeSelection()
{

    ImGuiIO& io = ImGui::GetIO();
    ImDrawList* drawList = ImGui::GetWindowDrawList();

    ImVec2 mousePos = io.MousePos;
    static ImVec2 m_StartPos, m_EndPos;

    if (IsMouseOnWindow()  && GetMarqueeSelectionFlag()) {
        if (io.MouseDown[0])
        {
            if (!m_MarqueeSelection && !m_IsAnyItemActive) {
                m_MarqueeSelection = true;
                m_StartPos = mousePos;
            }
        }
        if (m_MarqueeSelection) {
            m_EndPos = mousePos;
            drawList->AddRectFilled(m_StartPos, m_EndPos, IM_COL32(50, 150, 255, 50));
            drawList->AddRect(m_StartPos, m_EndPos, IM_COL32(50, 150, 255, 255));
        }

        if (!io.MouseDown[0] && m_MarqueeSelection) {
            m_MarqueeSelection = false;
            
            float minX = glm::min(m_StartPos.x, m_EndPos.x);
            float minY = glm::min(m_StartPos.y, m_EndPos.y);

            float maxX = glm::max(m_StartPos.x, m_EndPos.x);
            float maxY = glm::max(m_StartPos.y, m_EndPos.y);

            m_PosMin = { minX, minY };
            m_PosMax = { maxX, maxY };

            auto deltaPos = m_PosMax - m_PosMin;
            if (deltaPos.x > 5 && deltaPos.y > 5)
            {
                this->HandleSelection();

            }
        }
    }
}

void Layer::HandleSelection()
{

}


void Layer::Handle()
{
    {
        this->HandleFunc();
    }
    for (auto child : m_Children)
    {
        child->HandleFunc();
    }

}



void Layer::ViewFunc()
{
}

void Layer::HandleFunc()
{
}

bool fxcc::imgui::Layer::IsMouseOnWindow()
{
    const auto& windowSize = m_WindowSize;
    const auto& windowPos = m_WindowPos;

    ImGuiIO& io = ImGui::GetIO();
    return io.MousePos.x >= windowPos.x && io.MousePos.x <= (windowPos.x + windowSize.x) &&
        io.MousePos.y >= windowPos.y && io.MousePos.y <= (windowPos.y + windowSize.y);

}

void Layer::GetItemPos(ImVec2& minPos, ImVec2& maxPos)
{
    minPos = ImGui::GetItemRectMin();
    maxPos = ImGui::GetItemRectMax();

}

void fxcc::imgui::Layer::GetItemPos(fxcc::Base* item)
{
    item->m_StartPos= ImGui::GetItemRectMin();
    item->m_EndPos = ImGui::GetItemRectMax();

}

bool fxcc::imgui::Layer::ItemInSelectionRange(const fxcc::Base* it)
{
    const auto& itemMax = it->m_EndPos;
    const auto& itemMin = it->m_StartPos;
    const auto& minPos = m_PosMin;
    const auto& maxPos = m_PosMax;

    bool inXRange = itemMax.x >= minPos.x && itemMin.x <= maxPos.x;
    bool inYRange = itemMax.y >= minPos.y && itemMin.y <= maxPos.y;

    return inXRange && inYRange;
}